The C run-time library provides run-time error checking when you compile with /RTC (run-time checks) or use the run-time_checks pragma. In some cases, you may want to customize CRT run-time error checking:
To customize run-time error checking, you can:
A custom reporting function for run-time errors must have same declaration as _CrtDbgReport. It should return value of 1 to the debugger.
The following example shows how to define a custom reporting function:
int errorhandler = 0;
void configureMyErrorFunc(int i)
{
errorhandler = i;
}
int MyErrorFunc(int errorType, const char *filename, int linenumber, const char *moduleName, const char *format, ...)
{
switch (errorhandler)
{
case 0:
case 1:
printf("Error type %d at %s line %d in %s",errorType. filename, linenumber, moduleName);
case 2:
case 3:
fprintf(stderr, "Error type);
}
}
The following example shows a more complex custom reporting function. In this example, the switch statement handles various error types, as defined by the reportType parameter of _CrtDbgReport. Since you are replacing _CrtDbgReport, you cannot use _CrtSetReportMode. Your function must handle the output. The first variable argument in this function takes a run-time error number.
#include <windows.h>
#include <stdarg.h>
#pragma runtime_checks("", off)
int Catch_RTC_Failure(int errType, const char *file, int line, const char *module, const char *format, ...)
{
// Prevent re-entrancy
static long running = 0;
while (InterlockedExchange(&running, 1))
Sleep(0);
// Now, disable all RTC failures
int numErrors = _RTC_GetNumErrors();
int *errors=_alloca(numErrors);
for (int i = 0; i < numErrors; i++)
errors[i] = _RTC_SetErrorType(i, _RTC_ERRTYPE_IGNORE);
// First, let's get the rtc error number from the var-arg list...
va_list vl;
va_start(vl, format);
_RTC_ErrorNumber rtc_errnum = va_arg(vl, _RTC_ErrorNumber);
va_end(vl);
char buf[512];
const char *err = _RTC_GetErrDesc(rtc_errnum);
sprintf(buf, "%s\nLine #%d\nFile:%s\nModule:%s",
err,
line,
file ? file : "Unknown",
module ? module : "Unknown");
int res = (MessageBox(NULL, buf, "RTC Failed...", MB_YESNO) == IDYES) ? 1 : 0;
// Now, restore the RTC errortypes
for(i = 0; i < numErrors; i++)
_RTC_SetErrorType(i, errors[i]);
running = 0;
return res;
}
#pragma runtime_checks("", restore)
Use _RTC_SetErrorFunc to install your custom function in place of _CrtDbgReport. The _RTC_SetErrorFunc return value is the previous reporting function, which you can save and restore if necessary:
int main()
{
_RTC_error_fn oldfunction, newfunc;
oldfunction = _RTC_SetErrorFunc(&MyErrorFunc);
// run some code...
newfunc = _RTC_SetErrorFunc(oldfunction);
// newfunc == &MyErrorFunc;
// run some more code...
}
If you use _CrtDbgReport to report errors, you can use _CrtSetReportMode to specify the destination of error messages.
If you use a custom reporting function, use _RTC_SetErrorType to associate an error with a report type.
_RTC_NumErrors returns the number of error types detect by run-time error checks. To get a brief description of each error, you can loop from 0 to (_RTC_NumErrors –1) return value, passing the iteration value to _RTC_GetErrDesc on each loop.